#include <stdlib.h>
#include <stdio.h>
#include "../../plugins.h"
#include "../../gui_al.h"
#include "../../srch_pane.h"
#include "gui_al.h"
#include "gui_io.h"
#include "edit.h"
#include "undo.h"
#include "../../gui_io.h"
#include "../../callbacks.h"
#include "../../settings.h"
#include "../../tabs.h"


#define TAB_NAME "edit.so"

void *edit_view_menu = NULL;

GtkWidget *edt_box = NULL;

/*  Compiling this file:
 *  gcc -shared -o modules/plgn_example.so -L. -lejourn modules/plgn_example.c
 *  The -shared is to make it loadable dynamically, and -L. -lejourn is to tell
 *  it to dynamically load the ejourn libraries.
 */

GtkWidget *srch_page;






 /* init(gui) is called when the plugin is loaded.
  * gui will be NULL;
  */
void  ___init(void *ignoreme) 
{
  printf("Edit got tab number:%i\n", elog_tab_register(TAB_NAME));

  edt_box = elog_edit_initialize(_accel);
  gtk_container_add(GTK_CONTAINER(_notebook), edt_box);
  GtkWidget *edit_lbl = gtk_label_new(_("Edit"));
  gtk_notebook_set_tab_label(GTK_NOTEBOOK(_notebook),
							 gtk_notebook_get_nth_page(GTK_NOTEBOOK
													   (_notebook),
													   elog_tab_num(
																	TAB_NAME)),
							 edit_lbl);
  
  GtkTextBuffer *buffer =
	gtk_text_view_get_buffer(GTK_TEXT_VIEW(_mainTextView));
  g_signal_connect((gpointer) buffer, "insert-text",
				   G_CALLBACK(on_buffer_insert), NULL);
  gtk_widget_show_all(edt_box);
}
 
 /* end(void) is called when the program unloads your plugin.  Please clean
  * everything it's done up:  Including what it's added to the gui!
  * HINT:  You should have stored the gtk widgets you needed to delete them
  * later.
  */
void ___end(void *ignoreme)
{

}
 /* ugly(void) is called when the program exits but your plugin is still loaded.
  * It means you don't need to bother cleaning up memory really:  the kernel should
  * handle that for you and we just want that derned window to get off the users
  * desk.  So clean up what you need, save what you love, and finish it quickly if 
  * you can.
  * HINT:  A few Global state variables won't destroy the world here ;). 
  */
void ___ugly(void *ignoreme)
{
 
}
 
/*
void ___search(struct elog_plgn_data_srch *search)
{
  //not a concern
}
*/
void ___open(void *ignored)
{
  struct elog_plgn_data_io *in = (struct elog_plgn_data_io *)ignored;
  
  edit_gui_previewPane_set(in->doc);
  edit_gui_al_text(in->doc->text);
  edit_gui_io_clearUndo();
  edit_gui_io_clearRedo();	//clearing undo/redo buffers.
  edit_gui_al_setImage(in->doc->mood, in->doc->weather);
  int c;
  if (in->doc->links != NULL)
	for (c = 0; in->doc->links[c] != NULL; ++c)
	  in->doc->links[c]->num =
		edit_gui_al_textLink(in->doc->links[c]->start,
							 in->doc->links[c]->end,
							 in->doc->links[c]->href);
  elog_gui_al_page(ELOG_GUI_AL_PAGE_EDIT);
}


void *___save(void *data)
{
  struct elog_plgn_data_io *in = (struct elog_plgn_data_io *)data;
  struct elog_xml_doc *doc = in->doc;
  
  struct elog_xml_doc *current = elog_gui_getMeta();
  unsigned int len;
  
  unsigned char *txt =
	elog_sp_toUnsignedChar(edit_gui_al_text(NULL), &len);
  
  
  if (doc->text) free(doc->text);
  doc->text = txt;
  

  if (txt[0] == '\0') {
	free(txt);
	return 0; //this isn't an error, it's standard procedure.
  }


  //TODO:  xml should really be done with a dict
  //TODO:  Finish xml_dict, then use it for opening and saving
  //TODO:  xml files.  Then you can use it here too.
  //TODO:  It should probably be used for the plugin interactions too!

}

/* char *info returns user-level information about what the plugin does.
 */
char *___info()
{
  return "Edit Page -- This is the tab which you edit your entries with.";

} 
 
/* char *author returns the list of authors, please insert a \n after
 * each author for display purposes.
 */
char *___author()
{
  return "Tab Page by Chris <MA_D> Hilton";
}


void edt_tab_call_jumpPrev()
{
	elog_edit_view_prev_result();
}

void edt_tab_call_jumpNext()
{
	elog_edit_view_next_result();
}


void ___focus(void *ignoreme)
{
	if (!(edit_view_menu)) {
		edit_view_menu =
		    elog_gui_al_menu_new();
		elog_gui_al_view_add(edit_view_menu,
				     "Next Search Result",
				     edt_tab_call_jumpNext,
				     -1);
		elog_gui_al_view_add(edit_view_menu,
				     "Previous Search Result",
				     edt_tab_call_jumpPrev,
				     -1);
	}
	int n = elog_set_get_int("SEARCH_DIVIDE_1");
	if (n <= 0)
		n = elog_gui_al_width() - 128;
	elog_gui_al_srch_pane(n);
	elog_gui_al_menu_attach_view(edit_view_menu);
	elog_srch_pane_set_title("Occurances:");
	elog_tab_edit_srch();
}

void ___cut(void *ignoreme)
{
	elog_tab_edit_cut();
}

void ___copy(void *ignoreme)
{
	elog_tab_edit_cut(); 
}
void ___paste(void *ignoreme)
{
	elog_tab_edit_paste();
}
/*
 * This is the little menubar search function.  Not the main search.
 */
void ___srch(void *ignoreme)
{
	elog_tab_edit_srch();
}
void ___res(int *num)
{
	 int n = *num;
	 elog_tab_edit_res(NULL, n);
}

void ___undo(void *ignoreme)
{
	edit_gui_io_undo();
}

void ___redo(void *ignoreme)
{
	edit_gui_io_redo();
}

void ___delete(void *ignoreme)
{
	elog_tab_edit_delete();
}

